﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;

/// <summary>
/// Enemy spawner.
/// </summary>
public class SpawnPoint : MonoBehaviour
{
    /// <summary>
    /// Enemy wave structure.
    /// </summary>
    [System.Serializable]
    public class Wave
    {
        // Delay before wave run
        public float delayBeforeWave;
        // List of enemies in this wave
        public List<GameObject> enemies;
    }

    // Enemies will have different speed in specified interval
    public float speedRandomizer = 0.2f;
    // Delay between enemies spawn in wave
    public float unitSpawnDelay = 0.8f;
    // Waves list for this spawner
    public List<Wave> waves;
    // This list is used for random enemy spawn
    [HideInInspector]
    public List<GameObject> randomEnemiesList = new List<GameObject>();

    // Enemies will move along this pathway
    private Pathway path;
    // Buffer with active spawned enemies
    private List<GameObject> activeEnemies = new List<GameObject>();
    // All enemies were spawned
    private bool finished = false;

    void Awake()
    {
        path = GetComponentInParent<Pathway>();
        Debug.Assert(path != null, "Wrong initial parameters");
    }

    void OnEnable()
    {
        EventManager.StartListening("UnitDie", UnitDie);
        EventManager.StartListening("WaveStart", WaveStart);
    }

    void OnDisable()
    {
        EventManager.StopListening("UnitDie", UnitDie);
        EventManager.StopListening("WaveStart", WaveStart);
    }

    void Update()
    {
        if (finished && activeEnemies.Count <= 0)
        {
            EventManager.TriggerEvent("AllEnemiesAreDead", null, null);
            gameObject.SetActive(false);
        }
    }

    public void SetWaves(List<List<GameObject>> waveConfigs)
    {
        waves.Clear();
        foreach (var list in waveConfigs)
        {
            waves.Add(new Wave
            {
                delayBeforeWave = 0,
                enemies = new List<GameObject>(list)
            });
        }
    }

    private IEnumerator RunWave(int waveIdx)
    {
        if (waveIdx < waves.Count)
        {
            // 等待波次延迟
            yield return new WaitForSeconds(waves[waveIdx].delayBeforeWave);

            // 触发“WaveStarted”事件，传入当前 GameObject 和波次索引
            EventManager.TriggerEvent("WaveStarted", gameObject, waveIdx.ToString());

            // 开始生成这一波的所有敌人
            foreach (GameObject enemy in waves[waveIdx].enemies)
            {
                GameObject prefab = enemy;
                if (prefab == null && randomEnemiesList.Count > 0)
                {
                    prefab = randomEnemiesList[Random.Range(0, randomEnemiesList.Count)];
                }
                if (prefab == null)
                {
                    Debug.LogError("Have no enemy prefab. Please specify enemies in Level Manager or in Spawn Point");
                    continue;
                }

                GameObject newEnemy = Instantiate(prefab, transform.position, transform.rotation);
                var patrol = newEnemy.GetComponent<AiStatePatrol>();
                var unitInfo = newEnemy.GetComponent<UnitInfo>();
                Debug.Log($"实例化敌人：{newEnemy.name}，Buff列表：{string.Join(", ", unitInfo.buffs)}");
           
         
                if (patrol != null) patrol.path = path;
                

                var agent = newEnemy.GetComponent<NavAgent>();
                if (agent != null)
                {
                    agent.speed = Random.Range(agent.speed * (1f - speedRandomizer), agent.speed * (1f + speedRandomizer));
                }

                activeEnemies.Add(newEnemy);
                yield return new WaitForSeconds(unitSpawnDelay);
            }

            if (waveIdx + 1 == waves.Count)
            {
                finished = true;
            }

        }

    }

    private void UnitDie(GameObject obj, string param)
    {
        if (activeEnemies.Contains(obj))
        {
            activeEnemies.Remove(obj);
        }
    }

    private void WaveStart(GameObject obj, string param)
    {
        if (int.TryParse(param, out int waveIdx))
        {
            StartCoroutine(RunWave(waveIdx));
        }
        else
        {
            Debug.LogWarning($"Invalid wave index: {param}");
        }
    }

    void OnDestroy()
    {
        StopAllCoroutines();
    }
}

